using System;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Moq;
using Volo.Abp;
using Volo.Abp.Modularity;
using Xunit;

namespace MatrixFramework.Shared.Application.Testing
{
    /// <summary>
    /// 测试基类
    /// </summary>
    public abstract class TestBase
    {
        protected IServiceProvider ServiceProvider { get; }
        protected ILogger<TestBase> Logger { get; }

        protected TestBase()
        {
            var services = new ServiceCollection();
            ConfigureServices(services);
            ServiceProvider = services.BuildServiceProvider();
            Logger = ServiceProvider.GetRequiredService<ILogger<TestBase>>();

            BeforeTest();
        }

        protected virtual void BeforeTest()
        {
            // 子类可以重写此方法进行测试前的初始化
        }

        protected virtual void AfterTest()
        {
            // 子类可以重写此方法进行测试后的清理
        }

        /// <summary>
        /// 配置服务
        /// </summary>
        protected virtual void ConfigureServices(IServiceCollection services)
        {
            // 添加默认服务
            services.AddLogging(builder => builder.AddConsole());
            services.AddMemoryCache();
            services.AddSingleton<IDistributedCache>(new TestDistributedCache());
        }

        /// <summary>
        /// 获取服务
        /// </summary>
        protected T GetService<T>() where T : class
        {
            return ServiceProvider.GetRequiredService<T>();
        }

        /// <summary>
        /// 获取服务（可为null）
        /// </summary>
        protected T? GetOptionalService<T>() where T : class
        {
            return ServiceProvider.GetService<T>();
        }

        /// <summary>
        /// 创建Mock对象
        /// </summary>
        protected Mock<T> CreateMock<T>() where T : class
        {
            return new Mock<T>();
        }

        /// <summary>
        /// 配置选项
        /// </summary>
        protected void ConfigureOptions<T>(Action<T> configure) where T : class, new()
        {
            var options = new T();
            configure(options);
            var optionsService = ServiceProvider.GetService<IOptions<T>>();
            optionsService?.Value.Equals(options);
        }

        /// <summary>
        /// 执行操作（简化版本，不包含工作单元）
        /// </summary>
        protected async Task<TResult> ExecuteAsync<TResult>(Func<Task<TResult>> func)
        {
            return await func();
        }

        /// <summary>
        /// 执行操作（简化版本，不包含工作单元）
        /// </summary>
        protected async Task ExecuteAsync(Func<Task> func)
        {
            await func();
        }

        /// <summary>
        /// 断言异常
        /// </summary>
        protected void AssertThrows<TException>(Action action, string message = null) where TException : Exception
        {
            TException exception = null;
            try
            {
                action();
            }
            catch (TException ex)
            {
                exception = ex;
            }

            Assert.NotNull(exception);
            Assert.IsType<TException>(exception);

            if (!string.IsNullOrEmpty(message))
            {
                Assert.Contains(message, exception.Message);
            }
        }

        /// <summary>
        /// 断言异步异常
        /// </summary>
        protected async Task AssertThrowsAsync<TException>(Func<Task> action, string message = null) where TException : Exception
        {
            TException exception = null;
            try
            {
                await action();
            }
            catch (TException ex)
            {
                exception = ex;
            }

            Assert.NotNull(exception);
            Assert.IsType<TException>(exception);

            if (!string.IsNullOrEmpty(message))
            {
                Assert.Contains(message, exception.Message);
            }
        }

        /// <summary>
        /// 记录测试信息
        /// </summary>
        protected void LogTestInfo(string message)
        {
            Logger.LogInformation("[TEST] {Message}", message);
        }

        /// <summary>
        /// 记录测试警告
        /// </summary>
        protected void LogTestWarning(string message)
        {
            Logger.LogWarning("[TEST] {Message}", message);
        }

        /// <summary>
        /// 记录测试错误
        /// </summary>
        protected void LogTestError(string message, Exception? exception = null)
        {
            if (exception != null)
            {
                Logger.LogError(exception, "[TEST] {Message}", message);
            }
            else
            {
                Logger.LogError("[TEST] {Message}", message);
            }
        }
    }

    /// <summary>
    /// 应用服务测试基类
    /// </summary>
    public abstract class ApplicationServiceTestBase<TService> : TestBase where TService : class
    {
        protected TService Service { get; }
        protected Mock<TService> ServiceMock { get; }

        protected ApplicationServiceTestBase()
        {
            ServiceMock = CreateMock<TService>();
            Service = ServiceMock.Object;

            ConfigureServices();
        }

        protected virtual void ConfigureServices()
        {
            // 子类可以重写此方法配置额外的服务
        }

        /// <summary>
        /// 设置Mock对象的行为
        /// </summary>
        protected void SetupMock<T>(Action<Mock<T>> setup) where T : class
        {
            var mock = CreateMock<T>();
            setup(mock);
        }

        /// <summary>
        /// 验证Mock对象的调用
        /// </summary>
        protected void VerifyMock<T>(Action<Mock<T>> verify, Times? times = null) where T : class
        {
            var mock = GetOptionalService<Mock<T>>();
            if (mock != null)
            {
                verify(mock);
            }
        }
    }

    /// <summary>
    /// 域服务测试基类
    /// </summary>
    public abstract class DomainServiceTestBase<TService> : TestBase where TService : class
    {
        protected TService Service { get; }

        protected DomainServiceTestBase()
        {
            Service = GetService<TService>();
            SetupTestData();
        }

        protected virtual void SetupTestData()
        {
            // 子类可以重写此方法设置测试数据
        }

        /// <summary>
        /// 创建测试实体
        /// </summary>
        protected TEntity CreateTestEntity<TEntity>(Action<TEntity>? configure = null) where TEntity : class, new()
        {
            var entity = new TEntity();
            configure?.Invoke(entity);
            return entity;
        }
    }

    /// <summary>
    /// 缓存测试基类
    /// </summary>
    public abstract class CacheTestBase : TestBase
    {
        protected TestDistributedCache TestCache { get; }

        protected CacheTestBase()
        {
            TestCache = new TestDistributedCache();
            ConfigureServices();
        }

        protected virtual void ConfigureServices()
        {
            // 注册测试缓存
            var services = GetService<IServiceCollection>();
            services.AddSingleton<IDistributedCache>(_ => TestCache);
        }

        /// <summary>
        /// 验证缓存设置
        /// </summary>
        protected void AssertCacheSet(string key, object? value)
        {
            Assert.True(TestCache.ContainsKey(key));
            Assert.Equal(value, TestCache.Get(key));
        }

        /// <summary>
        /// 验证缓存未设置
        /// </summary>
        protected void AssertCacheNotSet(string key)
        {
            Assert.False(TestCache.ContainsKey(key));
        }

        /// <summary>
        /// 清空缓存
        /// </summary>
        protected void ClearCache()
        {
            TestCache.Clear();
        }
    }

    /// <summary>
    /// 测试用分布式缓存实现
    /// </summary>
    public class TestDistributedCache : IDistributedCache
    {
        private readonly Dictionary<string, byte[]> _cache = new();
        private readonly Dictionary<string, DateTime> _expiry = new();

        public byte[]? Get(string key)
        {
            if (_expiry.TryGetValue(key, out var expiry) && expiry <= DateTime.UtcNow)
            {
                _cache.Remove(key);
                _expiry.Remove(key);
                return null;
            }
            return _cache.TryGetValue(key, out var value) ? value : null;
        }

        public Task<byte[]?> GetAsync(string key, CancellationToken token = default)
        {
            return Task.FromResult(Get(key));
        }

        public void Set(string key, byte[] value, DistributedCacheEntryOptions? options)
        {
            _cache[key] = value;
            if (options?.AbsoluteExpiration != null)
            {
                _expiry[key] = options.AbsoluteExpiration.Value.UtcDateTime;
            }
        }

        public Task SetAsync(string key, byte[] value, DistributedCacheEntryOptions? options, CancellationToken token = default)
        {
            Set(key, value, options);
            return Task.CompletedTask;
        }

        public void Refresh(string key)
        {
            // 测试实现中不处理刷新
        }

        public Task RefreshAsync(string key, CancellationToken token = default)
        {
            Refresh(key);
            return Task.CompletedTask;
        }

        public void Remove(string key)
        {
            _cache.Remove(key);
            _expiry.Remove(key);
        }

        public Task RemoveAsync(string key, CancellationToken token = default)
        {
            Remove(key);
            return Task.CompletedTask;
        }

        // 测试辅助方法
        public bool ContainsKey(string key) => _cache.ContainsKey(key);
        public void Clear()
        {
            _cache.Clear();
            _expiry.Clear();
        }
    }

    /// <summary>
    /// 测试启动类
    /// </summary>
    public class TestStartup
    {
        public class Module : AbpModule
        {
            // 测试模块配置
        }
    }

    /// <summary>
    /// 测试数据构建器
    /// </summary>
    public abstract class TestDataBuilder<T>
    {
        protected T Data { get; set; }

        protected TestDataBuilder()
        {
            Data = CreateDefault();
        }

        protected abstract T CreateDefault();

        public T Build() => Data;

        public TestDataBuilder<T> With(Action<T> action)
        {
            action(Data);
            return this;
        }

        public static implicit operator T(TestDataBuilder<T> builder) => builder.Build();
    }

    /// <summary>
    /// 测试辅助方法
    /// </summary>
    public static class TestHelper
    {
        /// <summary>
        /// 创建随机Guid
        /// </summary>
        public static Guid RandomGuid() => Guid.NewGuid();

        /// <summary>
        /// 创建随机字符串
        /// </summary>
        public static string RandomString(int length = 10)
        {
            const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
            var random = new Random();
            return new string(Enumerable.Repeat(chars, length)
                .Select(s => s[random.Next(s.Length)]).ToArray());
        }

        /// <summary>
        /// 创建随机邮箱
        /// </summary>
        public static string RandomEmail() => $"{RandomString(8)}@{RandomString(5)}.com";

        /// <summary>
        /// 创建随机数字
        /// </summary>
        public static int RandomInt(int min = 1, int max = 1000) => new Random().Next(min, max);

        /// <summary>
        /// 创建随机日期
        /// </summary>
        public static DateTime RandomDate(DateTime? start = null, DateTime? end = null)
        {
            var start_date = start ?? DateTime.UtcNow.AddYears(-1);
            var end_date = end ?? DateTime.UtcNow;
            var range = end_date - start_date;
            var random = new Random();
            return start_date.AddDays(random.NextDouble() * range.TotalDays);
        }
    }
}